package boss.portal.controller;

import boss.portal.entity.logg.UserOptLoggerEntity;
import boss.portal.repository.UserOptLoggerRepository;
import boss.portal.service.IUserOptLogService;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Api(value = "API-用户操作日志", tags = {"API-用户操作日志"})
@RestController
@RequestMapping("/api/useropt/logger")
public class UserOptLoggerController {

    private String sdfFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
    private SimpleDateFormat sdf = new SimpleDateFormat(sdfFormat);

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private UserOptLoggerRepository userOptLoggerRepository;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @ApiOperation(value = "用户操作日志", tags = {"API-用户操作日志"}, notes = "/add")
    @PostMapping("/add")
    public Map<String, Object> add(HttpServletRequest request,
                                   @RequestBody @ApiParam UserOptLoggerEntity entity) throws IOException {

        entity.setIp(request.getRemoteAddr());
        entity.setOptTime(new Date());

        entity = userOptLoggerRepository.save(entity);
//        // 创建索引请求对象
//        IndexRequest indexUserOptLogger = new IndexRequest(IUserOptLogService.USER_OPT_LOGGER);
//        // 将对象转换为 byte 数组
//        byte[] json = JSON.toJSONBytes(entity);
//        // 设置文档内容
//        indexUserOptLogger.source(json, XContentType.JSON);
//        // 执行增加文档
//        IndexResponse response = restHighLevelClient.index(indexUserOptLogger, RequestOptions.DEFAULT);
//        log.info("创建状态：{}", response.status());

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", 0);
        map.put("msg", "success");
        map.put("data", entity);
        return map;
    }

    @ApiOperation(value = "用户操作日志", tags = {"API-用户操作日志"}, notes = "/list")
    @GetMapping("/list")
    public Object selectList(@RequestParam(value = "optModule", required = false) String optModule,
                             @RequestParam(value = "optType", required = false) String optType,
                             @RequestParam(value = "operator", required = false) String operator,
                             @RequestParam(value = "beginTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date beginTime,
                             @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date endTime,
                             @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                             @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) throws IOException {

        String firmSourceId = null;
        firmSourceId = (null == firmSourceId) ? "fltdkzkt" : firmSourceId;

        // 创建 Bool 查询构建器
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        RangeQueryBuilder rqb = null;
        if (null != beginTime) {
            rqb = QueryBuilders.rangeQuery("optTime").format(sdfFormat).gte(sdf.format(beginTime))
                    .includeLower(true)
                    .includeUpper(false);
        }
        if (null != endTime) {
            if (null == rqb) {
                rqb = QueryBuilders.rangeQuery("optTime").format(sdfFormat).lte(sdf.format(endTime))
                        .includeLower(false)
                        .includeUpper(true);
            } else {
                rqb = rqb.lte(sdf.format(endTime))
                        .includeLower(true)
                        .includeUpper(true);
            }
        }

        // 构建查询条件
        boolQueryBuilder.must(QueryBuilders.termsQuery("firmId", firmSourceId));
        if (null != optModule) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("optModule", optModule));
        }
        if (null != operator) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("operator", operator));
        }
        if (null != optType) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("optType", optType));
        }
        if (null != rqb) {
            boolQueryBuilder.filter().add(rqb);
        }

        // 构建查询源构建器
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.sort("optTime");
        searchSourceBuilder.from(pageSize * (page - 1));
        searchSourceBuilder.size(pageSize);

        // 创建查询请求对象，将查询对象配置到其中
        SearchRequest searchRequest = new SearchRequest(IUserOptLogService.USER_OPT_LOGGER);
        searchRequest.source(searchSourceBuilder);

        // 执行查询，然后处理响应结果
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 根据状态和数据条数验证是否返回了数据
        SearchHits hits = searchResponse.getHits();
        List<UserOptLoggerEntity> optLogger = new ArrayList<>();

        if (RestStatus.OK.equals(searchResponse.status()) && hits.getTotalHits().value > 0) {

            for (SearchHit hit : hits) {
                // 将 JSON 转换成对象
                UserOptLoggerEntity userOptLogger = JSON.parseObject(hit.getSourceAsString(), UserOptLoggerEntity.class);
                optLogger.add(userOptLogger);
            }
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", 0);
        map.put("msg", "success");
        map.put("data", optLogger);

        map.put("total", hits.getTotalHits());
        map.put("maxPage", Math.ceil(hits.getTotalHits().value * 1.0D / pageSize));

        return map;
    }
}
